07.b - UI-Components-&-Animations
Relevant source files
This document describes the reusable UI components and animation system used throughout the godeep.wiki frontend. The components implement interactive visual effects including hover states, mouse tracking, intersection-observer-based animations, and custom CSS keyframes. For information about the overall frontend architecture and routing structure, see 7. For information about theming and layout structure, see 7.1.
Component Architecture OverviewLink copied!
The UI component system consists of two categories: interactive components with hover effects and mouse tracking (BeamButton, SpotlightCard, IconGlow), and animation components that orchestrate entrance effects (FadeIn, BackgroundReveal). All components are client-side rendered using the "use client" directive and follow a composition pattern where they wrap child elements to enhance them with visual effects.
Component Architecture Diagram
Sources: app/page.tsx L1-L214
components/beam-button.tsx L1-L26
components/spotlight-card.tsx L1-L68
components/icon-glow.tsx L1-L20
components/background-reveal.tsx L1-L18
Interactive ComponentsLink copied!
BeamButton ComponentLink copied!
The BeamButton component wraps the shadcn/ui Button component with an animated gradient border effect that appears on hover. It creates a glowing "beam" effect using a blurred gradient background that fades in when the user hovers over the button.
Component Props:
| Prop | Type | Description |
|---|---|---|
children | React.ReactNode | Button content (text, icons, etc.) |
className | string (optional) | Additional CSS classes to merge with defaults |
...props | React.ComponentProps<typeof Button> | All standard Button props (type, size, etc.) |
Implementation Details:
The component structure consists of three layers defined in components/beam-button.tsx L11-L24
:
- Outer wrapper (
divwithrelative group inline-flex): Establishes positioning context and hover group - Gradient background (
divwithabsolute -inset-0.5): Animated blur gradient that expands on hover, usingbg-gradient-to-r from-blue-500 to-purple-600withopacity-0transitioning toopacity-100ongroup-hover - Button element: Styled with blue background, rounded-full shape, custom shadow effects, and border that becomes visible on hover
The glow effect is achieved through CSS shadow properties that intensify on hover:
- Default:
shadow-[0_0_20px_-5px_rgba(37,99,235,0.3)] - Hover:
shadow-[0_0_25px_-5px_rgba(37,99,235,0.5)]
Usage Example:
The component is used in app/page.tsx L63-L66
for the primary CTA button and app/page.tsx L182-L184
for the pricing CTA:
<form action={createCheckoutSession}> <BeamButton size="lg" type="submit"> Generate DeepWiki — $10 </BeamButton></form>
Sources: components/beam-button.tsx L1-L26
SpotlightCard ComponentLink copied!
The SpotlightCard component creates a card with an interactive "spotlight" effect that follows the user's mouse cursor. It renders two radial gradients that track mouse position: a subtle background glow and a more focused border highlight.
Component Props:
| Prop | Type | Description |
|---|---|---|
children | React.ReactNode | Card content to be wrapped |
className | string (optional) | Additional CSS classes (defaults to "") |
Mouse Tracking Implementation:
The component uses React refs and state to track mouse position, as shown in components/spotlight-card.tsx L11-L20
:
- State management: *
position: Stores{ x: number, y: number }relative to card bounds *opacity: Controls spotlight visibility (0 when not hovered, 1 when hovered) - Event handlers: *
handleMouseMove: Calculates cursor position relative to card bounds usinggetBoundingClientRect()*handleMouseEnter/handleMouseLeave: Toggle opacity state *handleFocus/handleBlur: Enable keyboard accessibility
Spotlight Rendering:
Two overlaid div elements create the spotlight effect in components/spotlight-card.tsx L48-L63
:
- Background glow: Radial gradient with 600px radius, 6% white opacity, 40% transparency fallback
- Border highlight: Same radius but 10% opacity, masked with 200px circle using
maskImageandWebkitMaskImagefor browser compatibility
Both use inline styles with dynamic background properties incorporating position.x and position.y:
radial-gradient(600px circle at ${position.x}px ${position.y}px, rgba(255,255,255,0.06), transparent 40%)
Usage Example:
The component wraps each "What You Get" feature card in app/page.tsx L117-L123
:
<SpotlightCard className="h-full"> <CardContent className="flex flex-col items-center justify-center p-6 space-y-3 text-center h-full"> <item.icon className="w-6 h-6 text-slate-500" /> <span className="text-sm text-slate-300 font-medium">{item.label}</span> </CardContent></SpotlightCard>
Sources: components/spotlight-card.tsx L1-L68
IconGlow ComponentLink copied!
The IconGlow component wraps icon elements with a hover-activated glow effect. It provides a consistent visual treatment for all icons in the "How It Works" section.
Component Props:
| Prop | Type | Description |
|---|---|---|
children | React.ReactNode | Icon component to wrap (typically Lucide icons) |
className | string (optional) | Additional CSS classes |
Effect Implementation:
The component structure defined in components/icon-glow.tsx L11-L18
uses the group/icon pattern for scoped hover effects:
- Outer wrapper:
relative group/icon inline-flexestablishes hover group context - Glow layer: Absolute positioned
divwithbg-blue-500/20,blur-lg, transitions fromopacity-0toopacity-100ongroup-hover/icon - Icon container: 12x12 rounded square with slate background, slate-800 border that transitions to
border-blue-500/50on hover, and background changes tobg-blue-500/10
The blur radius of the glow layer is blur-lg (16px), creating a soft diffuse effect around the icon container.
Usage Example:
Each step in the "How It Works" section uses IconGlow in app/page.tsx L75-L77
:
<IconGlow className="mx-auto"> <Github className="w-5 h-5 text-slate-400 group-hover/icon:text-blue-400 transition-colors" /></IconGlow>
The icon itself also changes color on hover using the group-hover/icon selector, creating a coordinated visual response.
Sources: components/icon-glow.tsx L1-L20
Animation ComponentsLink copied!
FadeIn ComponentLink copied!
The FadeIn component uses the Intersection Observer API to trigger entrance animations when elements scroll into view. It implements a scroll-triggered animation pattern that prevents animations from playing until the element is visible in the viewport.
Component Props:
| Prop | Type | Default | Description |
|---|---|---|---|
children | React.ReactNode | required | Content to animate |
className | string | "" | Additional CSS classes |
delay | number | 0 | Animation delay in milliseconds |
duration | number | 0.5 | Animation duration in seconds |
Intersection Observer Configuration:
The component sets up an observer in components/fade-in.tsx L16-L39
with these parameters:
const observer = new IntersectionObserver( ([entry]) => { if (entry.isIntersecting) { setIsVisible(true) observer.unobserve(entry.target) // Cleanup after triggering } }, { rootMargin: "0px 0px -50px 0px", // Trigger 50px before bottom edge threshold: 0.1, // Trigger when 10% visible })
Animation Control:
The component applies the animate-enter class defined in app/globals.css L142-L144
and controls its playback state via inline styles in components/fade-in.tsx L42-L50
:
style={{ animationDelay: `${delay}ms`, animationDuration: `${duration}s`, animationPlayState: isVisible ? "running" : "paused",}}
This ensures the animation is paused until the element becomes visible, preventing animations from playing off-screen.
Usage Pattern:
The landing page uses cascading delays to create staggered entrance effects. For example, the hero section in app/page.tsx L34-L68
uses delays of 0ms, 100ms, 200ms, and 300ms:
<FadeIn delay={0}> <div className="inline-flex items-center..."> <span className="flex h-2 w-2 rounded-full bg-blue-500..."></span> Think Deep Research for GitHub </div></FadeIn><FadeIn delay={100}> <h1 className="text-6xl md:text-8xl...">Your Private Code Wiki</h1></FadeIn><FadeIn delay={200}> <p className="text-2xl md:text-3xl...">Understand any repository instantly...</p></FadeIn>
The "What You Get" grid uses incremental 50ms delays per item in app/page.tsx L116-L124
:
{items.map((item, i) => ( <FadeIn key={i} delay={i * 50}> <SpotlightCard className="h-full">...</SpotlightCard> </FadeIn>))}
Sources: components/fade-in.tsx L1-L55
BackgroundReveal ComponentLink copied!
The BackgroundReveal component creates an animated vertical stripe pattern that reveals from top to bottom on page load. It renders six vertical columns that animate sequentially to create a "curtain reveal" effect.
Implementation:
The component in components/background-reveal.tsx L4-L17
generates six columns using array iteration:
<div className="fixed inset-0 z-[-1] flex pointer-events-none"> {[...Array(6)].map((_, i) => ( <div key={i} className="flex-1 bg-slate-900/20 border-r border-slate-800/20 animate-reveal" style={{ animationDelay: `${i * 0.1}s`, }} /> ))}</div>
Key Properties:
fixed inset-0: Covers entire viewport, fixed positioningz-[-1]: Renders behind all contentpointer-events-none: Allows mouse interactions to pass throughflex: Equal width columns usingflex-1- Sequential delays: 0s, 0.1s, 0.2s, 0.3s, 0.4s, 0.5s
The animate-reveal class applies the reveal-down keyframe animation defined in app/globals.css L146-L158
Usage:
The component is rendered once at the top of the landing page layout in app/page.tsx L15
:
<div className="min-h-screen bg-[#0B0C0E]..."> <BackgroundReveal /> {/* Rest of page content */}</div>
Sources: components/background-reveal.tsx L1-L18
CSS Animation SystemLink copied!
The global stylesheet defines custom CSS keyframe animations and utility classes that power the animation components. These animations use modern CSS properties including transform, filter, and clip-path.
Custom KeyframesLink copied!
@keyframes enter
Defined in app/globals.css L128-L140
this animation creates a fade-in-up effect with blur:
| Keyframe | Properties |
|---|---|
0% | opacity: 0, transform: translateY(10px), filter: blur(4px) |
100% | opacity: 1, transform: none, filter: none |
The animation moves elements 10px upward while fading in and removing a 4px blur, creating a smooth entrance effect. Duration and delay are controlled per-instance via inline styles.
@keyframes reveal-down
Defined in app/globals.css L146-L154
this animation uses clip-path to reveal elements from top to bottom:
| Keyframe | Properties |
|---|---|
0% | clip-path: inset(0 0 100% 0) (fully clipped from bottom) |
100% | clip-path: inset(0 0 0 0) (fully revealed) |
The inset() function syntax is inset(top right bottom left). Starting with inset(0 0 100% 0) clips the entire element from the bottom, and animating to inset(0 0 0 0) reveals it downward.
Animation Utility ClassesLink copied!
Component-to-Animation Mapping
.animate-enter Class
Defined in app/globals.css L142-L144
:
.animate-enter { animation: enter 0.6s both;}
The both keyword applies both forwards (maintains final state) and backwards (applies initial state during delay) fill modes. Default duration is 0.6 seconds but can be overridden via inline styles.
.animate-reveal Class
Defined in app/globals.css L156-L158
:
.animate-reveal { animation: reveal-down 1s cubic-bezier(0.77, 0, 0.175, 1) both;}
The custom cubic-bezier easing function (0.77, 0, 0.175, 1) creates a slow-start, fast-end easing curve that emphasizes the reveal motion. Duration is 1 second.
Sources: app/globals.css L128-L158
components/background-reveal.tsx L9
Component Composition PatternsLink copied!
The landing page demonstrates a consistent composition pattern where animation components wrap interactive components, which in turn wrap content.
Component Nesting Hierarchy
Pattern Implementation Examples:
- Animation + Interactive + Form (app/page.tsx L60-L68 ):
<FadeIn delay={300}> <div className="pt-4"> <form action={createCheckoutSession}> <BeamButton size="lg" type="submit"> Generate DeepWiki — $10 </BeamButton> </form> </div></FadeIn>
- Animation + Interactive + Content (app/page.tsx L116-L124 ):
<FadeIn key={i} delay={i * 50}> <SpotlightCard className="h-full"> <CardContent className="..."> <item.icon className="w-6 h-6 text-slate-500" /> <span className="text-sm text-slate-300 font-medium">{item.label}</span> </CardContent> </SpotlightCard></FadeIn>
- Animation + Interactive + Icon (app/page.tsx L74-L79 ):
<FadeIn delay={0} className="space-y-4 group"> <IconGlow className="mx-auto"> <Github className="w-5 h-5 text-slate-400 group-hover/icon:text-blue-400 transition-colors" /> </IconGlow> <h3 className="text-slate-200 font-medium">Connect GitHub</h3></FadeIn>
Sources: app/page.tsx L60-L68
State Management in Interactive ComponentsLink copied!
Interactive components manage local UI state using React hooks without requiring global state management. The state is ephemeral and tied to user interactions (mouse position, hover state, visibility).
State Management Comparison Table
| Component | State Variables | State Purpose | Persistence |
|---|---|---|---|
BeamButton | None | Uses CSS :hover pseudo-class | N/A - CSS-only |
SpotlightCard | position: {x, y}, opacity: number | Track mouse for spotlight effect | Component lifetime only |
IconGlow | None | Uses CSS group-hover/icon | N/A - CSS-only |
FadeIn | isVisible: boolean | Control animation playback | Component lifetime only |
BackgroundReveal | None | Pure CSS animation | N/A - CSS-only |
SpotlightCard State Flow
FadeIn State Flow
Sources: components/spotlight-card.tsx L11-L36
components/fade-in.tsx L13-L39
Performance ConsiderationsLink copied!
The component system implements several performance optimizations:
- IntersectionObserver Cleanup:
FadeInautomatically unobserves elements after triggering (components/fade-in.tsx L21-L22 ), preventing unnecessary observer callbacks. - Pointer Events Disabling:
BackgroundRevealusespointer-events-none(components/background-reveal.tsx L5 ) to ensure the decorative background doesn't interfere with user interactions. - CSS-Only Hover Effects:
BeamButtonandIconGlowuse pure CSS hover effects without JavaScript, offloading animation work to the browser's compositor thread. - Conditional Ref Checks: Interactive components check for ref existence before accessing properties (components/spotlight-card.tsx L16 ) to prevent errors during unmounting.
- Will-Change Optimization: While not explicitly set in the code, the transform and opacity animations automatically trigger GPU acceleration in modern browsers.
- Throttled Mouse Tracking:
SpotlightCarddoesn't throttle mouse move events, but the radial gradient calculations are efficient as they use CSS custom properties updated via inline styles.
Sources: components/fade-in.tsx L21-L22
components/spotlight-card.tsx L15-L20
components/background-reveal.tsx L5
Refresh this wiki
Last indexed: 23 November 2025 (922b35)
On this page
- UI Components & Animations
- Component Architecture Overview
- Interactive Components
- BeamButton Component
- SpotlightCard Component
- IconGlow Component
- Animation Components
- FadeIn Component
- BackgroundReveal Component
- CSS Animation System
- Custom Keyframes
- Animation Utility Classes
- Component Composition Patterns
- State Management in Interactive Components
- Performance Considerations
Ask Devin about godeep.wiki-jb
Syntax error in text
mermaid version 11.4.1